From 1de33533eb77befbc2eb80431d1003b9c317e2af Mon Sep 17 00:00:00 2001 From: robertlipe Date: Tue, 23 Jul 2013 06:35:53 +0000 Subject: [PATCH] Fix track filter to not "randomly" reorder points within a track when sub-second times are in play. Addresses problem reported March 26 2010 (sigh) by Klaus Rheinwald. --- gpsbabel/reference/track/split-raw.gpx | 168 ++++++++++++++++++ gpsbabel/reference/track/split-split.gpx | 206 +++++++++++++++++++++++ gpsbabel/testo.d/track.test | 8 + gpsbabel/trackfilter.cc | 41 +++-- 4 files changed, 410 insertions(+), 13 deletions(-) create mode 100644 gpsbabel/reference/track/split-raw.gpx create mode 100644 gpsbabel/reference/track/split-split.gpx diff --git a/gpsbabel/reference/track/split-raw.gpx b/gpsbabel/reference/track/split-raw.gpx new file mode 100644 index 000000000..e346a1a9b --- /dev/null +++ b/gpsbabel/reference/track/split-raw.gpx @@ -0,0 +1,168 @@ + + + + + + + + 77.800034 + + 0.023166 + TP000224 + 3d + + + 77.799362 + + 0.031641 + TP000225 + 3d + + + 77.798965 + + 0.051357 + TP000226 + 3d + + + 77.798965 + + 0.054567 + TP000227 + 3d + + + 77.798462 + + 0.056182 + TP000228 + 3d + + + 77.798309 + + 0.066637 + TP000229 + 3d + + + 77.797417 + + 0.071383 + TP000230 + 3d + + + 77.795921 + + 0.081816 + TP000231 + 3d + + + 77.794380 + + 0.072754 + TP000232 + 3d + + + 77.792450 + + 0.078225 + TP000233 + 3d + + + 77.791138 + + 0.076833 + TP000234 + 3d + + + 77.790253 + + 0.088488 + TP000235 + 3d + + + 77.786873 + + 0.103797 + TP000236 + 3d + + + 77.784561 + + 0.103352 + TP000237 + 3d + + + 77.782021 + + 0.087818 + TP000238 + 3d + + + 77.780220 + + 0.081600 + TP000239 + 3d + + + 77.780632 + + 0.078945 + TP000240 + 3d + + + 77.780319 + + 0.083918 + TP000241 + 3d + + + 77.779068 + + 0.100007 + TP000242 + 3d + + + 77.778175 + + 0.099195 + TP000243 + 3d + + + 77.777702 + + 0.096335 + TP000244 + 3d + + + 77.777336 + + 0.097903 + TP000245 + 3d + + + + diff --git a/gpsbabel/reference/track/split-split.gpx b/gpsbabel/reference/track/split-split.gpx new file mode 100644 index 000000000..c00f60345 --- /dev/null +++ b/gpsbabel/reference/track/split-split.gpx @@ -0,0 +1,206 @@ + + + + + + 20100325194808 + + + 77.800034 + + 0.023166 + TP000224 + 3d + + + + + 77.799362 + + 0.031641 + TP000225 + 3d + + + + + 77.798965 + + 0.051357 + TP000226 + 3d + + + + + 77.798965 + + 0.054567 + TP000227 + 3d + + + + + 77.798462 + + 0.056182 + TP000228 + 3d + + + + + 77.798309 + + 0.066637 + TP000229 + 3d + + + + + 77.797417 + + 0.071383 + TP000230 + 3d + + + + + 77.795921 + + 0.081816 + TP000231 + 3d + + + + + 77.794380 + + 0.072754 + TP000232 + 3d + + + + + 77.792450 + + 0.078225 + TP000233 + 3d + + + + + 77.791138 + + 0.076833 + TP000234 + 3d + + + + + 77.790253 + + 0.088488 + TP000235 + 3d + + + + + 77.786873 + + 0.103797 + TP000236 + 3d + + + + + 77.784561 + + 0.103352 + TP000237 + 3d + + + + + 77.782021 + + 0.087818 + TP000238 + 3d + + + + + 77.780220 + + 0.081600 + TP000239 + 3d + + + + + 77.780632 + + 0.078945 + TP000240 + 3d + + + + + 77.780319 + + 0.083918 + TP000241 + 3d + + + + + 77.779068 + + 0.100007 + TP000242 + 3d + + + + + 77.778175 + + 0.099195 + TP000243 + 3d + + + + + 77.777702 + + 0.096335 + TP000244 + 3d + + + + + 77.777336 + + 0.097903 + TP000245 + 3d + + + + diff --git a/gpsbabel/testo.d/track.test b/gpsbabel/testo.d/track.test index 460735b10..066ff83b5 100644 --- a/gpsbabel/testo.d/track.test +++ b/gpsbabel/testo.d/track.test @@ -27,3 +27,11 @@ compare ${REFERENCE}/track/trk_reverse_test-rev.gpx ${TMPDIR}/trk_reverse_test-r # seg2trk filter test gpsbabel -i gpx -f ${REFERENCE}/track/seg2trk_test.gpx -x track,seg2trk -o gpx -F ${TMPDIR}/seg2trk_test-seg.gpx compare ${REFERENCE}/track/seg2trk_test-seg.gpx ${TMPDIR}/seg2trk_test-seg.gpx + +# Verify that the merge/split code is numerically stable on subsecond input. +# This would fail on GPSBabel <= 1.4.4 which didn't handle subsecond times +# correctly in this filter. Observe that the times in split-split are +# always ascending and the order of the input track names is preserved. + +gpsbabel -i gpx -f ${REFERENCE}/track/split-raw.gpx -x track,merge,split=1m -o gpx -F ${TMPDIR}/split-raw-split.gpx +compare ${REFERENCE}/track/split-split.gpx ${TMPDIR}/split-raw-split.gpx diff --git a/gpsbabel/trackfilter.cc b/gpsbabel/trackfilter.cc index f8c0a01c6..b66cab2b9 100644 --- a/gpsbabel/trackfilter.cc +++ b/gpsbabel/trackfilter.cc @@ -1,7 +1,7 @@ /* Track manipulation filter - Copyright (c) 2009, 2010 Robert Lipe, robertlipe@gpsbabel.org + Copyright (c) 2009 - 2013 Robert Lipe, robertlipe@gpsbabel.org Copyright (C) 2005-2006 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify @@ -176,8 +176,8 @@ arglist_t trackfilter_args[] = { typedef struct trkflt_s { route_head *track; - time_t first_time; - time_t last_time; + QDateTime first_time; + QDateTime last_time; } trkflt_t; static trkflt_t *track_list = NULL; @@ -259,8 +259,16 @@ trackfilter_init_qsort_cb(const void *a, const void *b) { const trkflt_t *ra = (const trkflt_t*) a; const trkflt_t *rb = (const trkflt_t*) b; + const QDateTime dta = ra->first_time; + const QDateTime dtb = rb->first_time; - return ra->first_time - rb->first_time; + if (dta > dtb) { + return 1; + } + if (dta == dtb) { + return 0; + } + return -1; } static int @@ -268,8 +276,16 @@ trackfilter_merge_qsort_cb(const void *a, const void *b) { const waypoint *wa = *(waypoint **)a; const waypoint *wb = *(waypoint **)b; + const QDateTime dta = wa->GetCreationTime(); + const QDateTime dtb = wb->GetCreationTime(); - return wa->GetCreationTime() - wb->GetCreationTime(); + if (dta > dtb) { + return 1; + } + if (dta == dtb) { + return 0; + } + return -1; } static fix_type @@ -366,11 +382,12 @@ trackfilter_fill_track_list_cb(const route_head *track) /* callback for track_d *******************************************************************************/ static void -trackfilter_split_init_rte_name(route_head *track, const time_t time) +trackfilter_split_init_rte_name(route_head *track, const QDateTime dt) { char buff[128], tbuff[128]; struct tm tm; + time_t time = dt.toTime_t(); tm = *localtime(&time); (opt_interval != 0) ? @@ -760,8 +777,9 @@ trackfilter_move(void) wpt = (waypoint *)elem; wpt->creation_time += delta; } - track_list[i].first_time += delta; - track_list[i].last_time += delta; + + track_list[i].first_time = track_list[i].first_time.addSecs(delta); + track_list[i].last_time = track_list[i].last_time.addSecs(delta); } } @@ -1209,7 +1227,7 @@ trackfilter_init(const char *args) } if (count > 0) { - track_list = (trkflt_t *) xcalloc(count, sizeof(*track_list)); + track_list = new trkflt_t[count]; /* check all tracks for time and order (except merging) */ @@ -1223,10 +1241,7 @@ trackfilter_init(const char *args) static void trackfilter_deinit(void) { - if (track_list != NULL) { - xfree(track_list); - track_list = NULL; - } + delete[] track_list; track_ct = 0; track_pts = 0; } -- 2.30.2